package com.platform.modules.sys.controller;

import com.platform.common.utils.SpringContextUtils;
import com.platform.config.XlingConstants;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.platform.common.annotation.SysLog;
import com.platform.common.exception.BusinessException;
import com.platform.common.utils.Constant;
import com.platform.common.utils.RestResponse;
import com.platform.common.validator.ValidatorUtils;
import com.platform.common.validator.group.AddGroup;
import com.platform.common.validator.group.UpdateGroup;
import com.platform.modules.sys.entity.SysDictEntity;
import com.platform.modules.sys.entity.SysMenuEntity;
import com.platform.modules.sys.entity.SysOrgEntity;
import com.platform.modules.sys.entity.SysUserEntity;
import com.platform.modules.sys.service.ShiroService;
import com.platform.modules.sys.service.SysDictService;
import com.platform.modules.sys.service.SysMenuService;
import com.platform.modules.sys.service.SysOrgService;
import com.platform.modules.sys.service.SysOrgUserService;
import com.platform.modules.sys.service.SysUserService;

/**
 * 系统菜单
 *
 * @author 肖亮
 */
@Api(tags = "SysMenuController|系统菜单管理")
@RestController
@RequestMapping("/sys/menu")
public class SysMenuController extends AbstractController {
	@Autowired
	private SysMenuService sysMenuService;
	@Autowired
	private ShiroService shiroService;
	@Autowired
	private SysDictService sysDictService;
	@Autowired
	private SysOrgService orgService;
	@Autowired
	private SysUserService userService;
	@Autowired
	private SysOrgUserService sysOrgUserService;


	/**
	 * 导航菜单
	 * 
	 * @return RestResponse
	 */
	@GetMapping("/nav")
	public RestResponse nav() {
		List<SysMenuEntity> menuList = sysMenuService.getUserMenuList(getUserId());
		Set<String> permissions = shiroService.getUserPermissions(getUserId());

		Map<String, Object> map = new HashMap<>(2);

		List<SysDictEntity> dictList = sysDictService.queryAll(map);
		List<SysOrgEntity> orgList = orgService.list();
		List<SysUserEntity> userList = userService.list(new QueryWrapper<SysUserEntity>().select("USER_ID,REAL_NAME"));
		return RestResponse.success().put("menuList", menuList).put("permissions", permissions)
				.put("dictList", dictList).put("orgList", orgList).put("userList", userList);
	}

	/**
	 * 导航菜单
	 *
	 * @return RestResponse  
	 */
	@GetMapping("/userNav")
	public RestResponse userNav() {
		List<SysMenuEntity> menuList = sysMenuService.getUserMenuList(getUserId());
		Map<String, Object> result = new HashMap<String, Object>();

		// 是否包含 SWAGGER
		if(SpringContextUtils.getActiveProfiles().contains(XlingConstants.SPRING_PROFILE_SWAGGER)){
			SysMenuEntity entity = new SysMenuEntity();
			entity.setMenuId("1504");
			entity.setName("接口文档");
			entity.setUrl("swagger-ui/index.html");
			entity.setType(1);
			entity.setIcon("&#xe60a;");
			menuList.add(entity);
		}

		result.put("menuList", menuList);
		result.put("org", getOrg());
		result.put("user", getUser());
		return RestResponse.success().put("result", result);
	}

	/**
	 * 所有菜单列表
	 *  
	 * @return RestResponse
	 */
	@ApiOperation(value = "所有菜单列表", notes = "所有菜单列表")
	@GetMapping("/list")
	//@RequiresPermissions("sys:menu:list")
	public Map<String, Object> list() {
		List<SysMenuEntity> menuList = sysMenuService.queryList();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("code", 0);
		map.put("msg", "");
		map.put("count", menuList.size());
		map.put("data", menuList);
		return map;
	}
	
	
	/**
	 * 根据菜单所属类型查询菜单
	 *     
	 * @return RestResponse
	 */
	@ApiOperation(value = "根据菜单所属类型查询菜单", notes = "根据菜单所属类型查询菜单")
	@ApiImplicitParams({
		@ApiImplicitParam(paramType = "query", name = "menuOrgType", value = "单位类型",required = false, dataType = "String")
    })
	@PostMapping("/menuOrgType")
	//@RequiresPermissions("sys:menu:list")
	public RestResponse listByOrgType(String menuOrgType) {
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("menuOrgType", menuOrgType);
		map.put("parentId", "0");
		List<SysMenuEntity> menuList = sysMenuService.queryMenuList(map);
		for(SysMenuEntity sysMenuEntity:menuList){
			String menuId = sysMenuEntity.getMenuId();
			List<SysMenuEntity> list = sysMenuService.queryListParentId(menuId);
			if(list != null && list.size()>0){
				for(SysMenuEntity menuEntity:list){
					List<SysMenuEntity> childrenlist = sysMenuService.queryListParentId(menuEntity.getMenuId());
					if(childrenlist !=null && childrenlist.size()>0){
						menuEntity.setChildren(childrenlist);
					}
				}
			}
			if(list != null && list.size()>0){
				sysMenuEntity.setChildren(list);
			}
		}
		return RestResponse.success().put("result", menuList);
	}
	
	
	
	/**
	 * 根据菜单所属单位类型查询菜单
	 *  
	 * @return RestResponse
	 */
	@ApiOperation(value = "查询单位类型菜单", notes = "查询单位类型菜单")
	@PostMapping("/orgTypeList")
	//@RequiresPermissions("sys:menu:list")
	public Map<String, Object> orgTypeList() {
		
		SysMenuEntity sysMenuEntity = new SysMenuEntity();
		sysMenuEntity.setParentId("0");
		
//		List<SysMenuEntity> menuList = sysMenuService.queryListParentId(sysMenuEntity);
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("code", 0);
		map.put("msg", "");
//		map.put("count", menuList.size());
//		map.put("data", menuList);
		return map;

		// return menuList;// RestResponse.success().put("menuList", menuList);
	}
	

	/**
	 * 选择菜单(添加、修改菜单)
	 *
	 * @return RestResponse
	 */
	@ApiOperation(value = "选择菜单", notes = "选择菜单")
	@GetMapping("/select")
	//@RequiresPermissions("sys:menu:select")
	public List<SysMenuEntity> select() {
		// 查询列表数据
		List<SysMenuEntity> menuList = sysMenuService.getAllNotButtonMenuList();
		return menuList;
	}

	/**
	 * 根据主键查询详情
	 *
	 * @param menuId
	 *            主键
	 * @return RestResponse
	 */
	@ApiOperation(value = "根据menuId查询菜单", notes = "根据menuId查询菜单")
	@ApiImplicitParams({
		@ApiImplicitParam(paramType = "query", name = "menuId", value = "菜单id",required = false, dataType = "String")
    })
	@PostMapping("/info")
	//@RequiresPermissions("sys:menu:info")
	public RestResponse info(String menuId) {
		SysMenuEntity menu = sysMenuService.getById(menuId);
		if (menu != null && menu.getParentId() != null) {
			SysMenuEntity menuParent = sysMenuService.getById(menu.getParentId());
			menu.setParentName(menuParent.getName());
		}
		return RestResponse.success().put("menu", menu);
	}

	/**
	 * 保存
	 * 
	 * @param menu
	 *            menu
	 * @return RestResponse
	 */
	@ApiOperation(value = "保存菜单", notes = "保存菜单")
	@SysLog("保存菜单")
	@PostMapping("/save")
	//@RequiresPermissions("sys:menu:save")
	public RestResponse save(SysMenuEntity menu) {
		ValidatorUtils.validateEntity(menu, AddGroup.class);
		// 数据校验
		if(!menu.getType().equals(Constant.STR_ZERO)&&(menu.getParentId()==null||menu.getParentId().equals(""))){ //如果是目录，允许为0
			return RestResponse.error("请选择上级目录");
		}
		verifyForm(menu);
		sysMenuService.add(menu);
		return RestResponse.success();
	}

	/**
	 * 修改
	 *
	 * @param menu
	 *            menu
	 * @return RestResponse
	 */
	@ApiOperation(value = "修改菜单", notes = "修改菜单")
	@SysLog("修改菜单")
	@PostMapping("/update")
	//@RequiresPermissions("sys:menu:update")
	public RestResponse update(SysMenuEntity menu) {
		ValidatorUtils.validateEntity(menu, UpdateGroup.class);
		// 数据校验
		verifyForm(menu);
		sysMenuService.updateById(menu);
		return RestResponse.success();
	}

	/**
	 * 删除
	 *
	 * @param menuId
	 *            主键
	 * @return RestResponse
	 */
	@ApiOperation(value = "根据menuId删除菜单", notes = "根据menuId删除菜单")
	@ApiImplicitParams({
		@ApiImplicitParam(paramType = "query", name = "menuId", value = "菜单id",required = false, dataType = "String")
    })
	@SysLog("删除菜单")
	@PostMapping("/delete")
	//@RequiresPermissions("sys:menu:delete")
	public RestResponse delete(String menuId) {
		// 判断是否有子菜单或按钮
		List<SysMenuEntity> menuList = sysMenuService.queryListParentId(menuId);
		if (menuList.size() > 0) {
			return RestResponse.error("请先删除子菜单或按钮");
		}
		sysMenuService.delete(menuId);
		return RestResponse.success();
	}

	/**
	 * 验证参数是否正确
	 *
	 * @param menu
	 *            menu
	 */
	@ApiOperation(value = "验证参数是否正确", notes = "验证参数是否正确")
	@SysLog("修改菜单")
	@PostMapping("/verifyForm")
	private void verifyForm(SysMenuEntity menu) {
		if (StringUtils.isBlank(menu.getName())) {
			throw new BusinessException("菜单名称不能为空");
		}

		if (menu.getParentId() == null) {
			throw new BusinessException("上级菜单不能为空");
		}

		// 菜单
		if (menu.getType() == Constant.MenuType.MENU.getValue()) {
			if (StringUtils.isBlank(menu.getUrl())) {
				throw new BusinessException("菜单URL不能为空");
			}
		}

		// 上级菜单类型
		int parentType = Constant.MenuType.CATALOG.getValue();
		if (!Constant.STR_ZERO.equals(menu.getParentId())) {
			SysMenuEntity parentMenu = sysMenuService.getById(menu.getParentId());
			parentType = parentMenu.getType();
		}

		// 目录、菜单
		if (menu.getType() == Constant.MenuType.CATALOG.getValue()
				|| menu.getType() == Constant.MenuType.MENU.getValue()) {
			if (parentType != Constant.MenuType.CATALOG.getValue()) {
				throw new BusinessException("上级菜单只能为目录类型");
			}
			return;
		}

		// 按钮
		if (menu.getType() == Constant.MenuType.BUTTON.getValue()) {
			if (parentType != Constant.MenuType.MENU.getValue()) {
				throw new BusinessException("上级菜单只能为菜单类型");
			}
		}
	}
}
